Skip to content

Refactor: unify image export format/encoding into ImageExportFormat + NSImage.encoded#13

Merged
GamalAnwar merged 1 commit into
masterfrom
claude/solid-refactor-editor-export
Jun 18, 2026
Merged

Refactor: unify image export format/encoding into ImageExportFormat + NSImage.encoded#13
GamalAnwar merged 1 commit into
masterfrom
claude/solid-refactor-editor-export

Conversation

@GamalAnwar

Copy link
Copy Markdown
Contributor

Summary

Target 2 (the editor export/save pipeline). EditorView.writeImageSync chose PNG vs JPEG-0.9 by file extension and inlined both encoders. That JPEG branch duplicated CaptureManager.saveJPEG, and CaptureHistoryStore.writeThumbnail duplicated both the JPEG encoder and the thumbnail sizing math — the latter already extracted as ThumbnailGeometry in #10. So this slice collapses three copies of "encode an NSImage to data" down to one.

New Utils/ImageExportFormat.swift:

enum ImageExportFormat: Equatable { case png; case jpeg(quality: Double)
    static func forPath(_ path: String) -> ImageExportFormat   // .jpg/.jpeg → jpeg(0.9), else png
}
extension NSImage { func encoded(as: ImageExportFormat) -> Data? }   // reuses pngData; one JPEG path

Call sites rewired

  • EditorView.writeImageSync — the extension if/inline encoders become image.encoded(as: .forPath(path)).
  • CaptureManager.saveJPEGimage.encoded(as: .jpeg(quality: quality)).
  • CaptureHistoryStore.writeThumbnail — now uses ThumbnailGeometry.fittedSize(...) for sizing and thumb.encoded(as: .jpeg(quality: 0.7)) for encoding (previously a full re-implementation of both).

Scope / safety

  • Behavior-preserving — identical format choice (extension match is still case-insensitive via lowercased()), identical compression factors (0.9 editor / 0.7 thumbnails), identical PNG path via the existing pngData.
  • No I/O moved — FileManager writes stay at the call sites.

Tests

ImageExportFormatTests (8 cases): forPath for png/jpg/jpeg, case-insensitive matching, unknown/missing extension → png; and encoded(as:) produces data with the correct PNG (\x89PNG) and JPEG (FFD8FF) signatures.

🤖 Generated with Claude Code


Generated by Claude Code

… NSImage.encoded

EditorView.writeImageSync chose PNG vs JPEG-0.9 by file extension and inlined
both encoders; the JPEG branch duplicated CaptureManager.saveJPEG, and
CaptureHistoryStore.writeThumbnail duplicated both the JPEG encoder and the
thumbnail sizing math (the latter already extracted as ThumbnailGeometry in #10).

Add ImageExportFormat (.png / .jpeg(quality), plus .forPath(_:) extension
decision) and a single NSImage.encoded(as:) encoder. Rewire all three call sites:
EditorView.writeImageSync, CaptureManager.saveJPEG, and
CaptureHistoryStore.writeThumbnail (now also using ThumbnailGeometry).

Behavior-preserving. Adds ImageExportFormatTests (8 cases) covering the path
decision and PNG/JPEG signatures of the encoded data.
@GamalAnwar GamalAnwar merged commit 880c98a into master Jun 18, 2026
1 check passed
@GamalAnwar GamalAnwar deleted the claude/solid-refactor-editor-export branch June 18, 2026 07:35
GamalAnwar added a commit that referenced this pull request Jun 18, 2026
… NSImage.encoded (#13)

Add ImageExportFormat (.png/.jpeg(quality) + .forPath decision) and a single
NSImage.encoded(as:) encoder. Collapse three inline/duplicated image encoders
(EditorView.writeImageSync, CaptureManager.saveJPEG, CaptureHistoryStore.
writeThumbnail) onto it, and route the history thumbnail's sizing through
ThumbnailGeometry too. Behavior-preserving. Adds ImageExportFormatTests (8 cases).
CI green.
GamalAnwar added a commit that referenced this pull request Jun 18, 2026
… NSImage.encoded (#13)

Add ImageExportFormat (.png/.jpeg(quality) + .forPath decision) and a single
NSImage.encoded(as:) encoder. Collapse three inline/duplicated image encoders
(EditorView.writeImageSync, CaptureManager.saveJPEG, CaptureHistoryStore.
writeThumbnail) onto it, and route the history thumbnail's sizing through
ThumbnailGeometry too. Behavior-preserving. Adds ImageExportFormatTests (8 cases).
CI green.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants